package com.uyii.springbootmongo.controller;

import com.uyii.springbootmongo.document.User;
import com.uyii.springbootmongo.repository.UserRepository;
import com.uyii.springbootmongo.vo.demoVo;
import com.uyii.springbootmongo.vo.userVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.mongodb.core.aggregation.*;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.web.bind.annotation.*;

import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.MongoTemplate;

import java.util.List;

@RestController
@RequestMapping("/users")
public class UserController {

    @Autowired
    private UserRepository userRepository;

    @Autowired
    private MongoTemplate mongoTemplate;

    @PostMapping
    public User createUser(@RequestBody User user) {
        return userRepository.save(user);
    }

    @GetMapping("/{id}")
    public User getUser(@PathVariable String id) {
        return userRepository.findById(id).orElse(null);
    }

    @DeleteMapping("/{id}")
    public void deleteUser(@PathVariable String id) {
        userRepository.deleteById(id);
    }

    @PutMapping("/{id}")
    public User updateUser(@PathVariable String id, @RequestBody User user) {
        User userFromDb = userRepository.findById(id).orElse(null);
        if (userFromDb != null) {
            userFromDb.setName(user.getName());
            userFromDb.setAge(user.getAge());
            return userRepository.save(userFromDb);
        }
        return null;
    }

    @GetMapping
    public Iterable<User> getAllUsers() {
        return userRepository.findAll();
    }

    /**
     * 查询年龄等于指定值的文档数量
     */
    @GetMapping("/count-by-age")
    public AggregationResults<demoVo> countByAge(@RequestParam int age) {
        // 创建匹配操作，用于筛选年龄等于指定值的文档
        MatchOperation match = Aggregation.match(Criteria.where("age").is(age));

        // 创建分组操作，按年龄分组并计算每个年龄的文档数量
        GroupOperation group = Aggregation.group("age").count().as("count");

        // 创建投影操作，将分组后的结果中的计数值重命名为"count"，并保留原始的"_id"字段（即年龄）
        ProjectionOperation project = Aggregation.project("count").and("_id").as("age");

        // 创建聚合管道，将匹配、分组和投影操作组合在一起
        Aggregation aggregation = Aggregation.newAggregation(match, group, project);

        // 使用MongoTemplate执行聚合操作，并将结果映射到demoVo类
        return mongoTemplate.aggregate(aggregation, "users", demoVo.class);
    }

    @GetMapping("/criteriaSelect")
    public List<User> criteriaSelect(@RequestParam String name, @RequestParam int age1, @RequestParam int age2) {
        Criteria criteria = new Criteria();
        criteria.and("name").regex(name);
        criteria.and("age").gt(age1).lt(age2);

        return mongoTemplate.find(new Query(criteria), User.class);
    }

    @GetMapping("/query")
    public List<User> query(@RequestParam String name, @RequestParam int minAge,  @RequestParam int maxAge) {

        // 两种写法看个人喜好，效果一样

        // 写法一
//        Criteria criteria = new Criteria();
//        criteria.and("name").regex(name);
//        criteria.and("age").gt(minAge).lt(maxAge);
//        return mongoTemplate.find(new Query(criteria), User.class);

        // 写法二
        Query query = new Query();
        query.addCriteria(Criteria.where("name").regex(name));
        query.addCriteria(Criteria.where("age").gt(minAge).lt(maxAge));
        return mongoTemplate.find(query, User.class);
    }

    @GetMapping("/findByAge")
    public List<User> findByAge(@RequestParam int age) {
        return userRepository.findByAgeGreaterThan(age);
    }

    @GetMapping("/findByAge")
    public List<userVo> findByAge() {
        return userRepository.findAllNamesAndAges();
    }
}